﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.DirectoryServices;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using UDataBaseWork;
using UEntity.LogEntity;
using XF.Common;
using XF.Meeting.DAL;
using XF.Meeting.Entity.ADEntity;
using XF.Meeting.Entity.DTO;
using XF.Meeting.IDal;

namespace AD.Manage
{
    public class ADSync
    {
        private static CBaseDB m_db;
        //private readonly string DcPath = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["DCPath"]));
        private readonly string DcRoot = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["DCRoot"]));
        private readonly string strObjectClassNames = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ObjectClassNames"]));
        private readonly string strTreeObjectClassNames = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ContainerObjectClassNames"]));
        private readonly string ADAccount = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ADAccount"]));
        private readonly string ADPassword = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ADPassword"]));
        string strSqlConn = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["SQLConnString"]));//
        ISettingDal settingdal = new SettingDal();
        //string DcPath = "";
        //string DcRoot = "";
        public ADSync()
        {
            //string strError = string.Empty;
            //var ad = TableToList.ToList<ADSetting>(settingdal.GetADsetting(out strError).Result);
            // DcPath = ad[0].DCPath;
            //DcRoot = ad[0].DCRoot;
            string strSqlConn = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["SQLConnString"]));//
            //string strSqlConn = UCommonWork.Common.Commons.MD5DecodeString(Convert.ToString("992A1EAE72D8AEBD5626AA7DDCE85149854D7E6D4000487EE3C724EFD97087C3F18AA02EDC280B54A0EA7D47D56ABAD983E689F4B461BA7792D2573131A10F6DBD61D37A26F70E384A2793FD6AA45A43004FAEE4535666A3"));
            m_db = new CBaseDB(strSqlConn);

        }

        

        public  Task<(bool, DataTable, DataTable)> ADSyncManage(string DcPath)
        {
            DataTable oudt = new DataTable();
            DataTable userdt = new DataTable();
            string strError = string.Empty;
            bool bResult = true;
            List<OUEntity> OuList = new List<OUEntity>();
            List<UserEntity> UserList = new List<UserEntity>();
            
            List<DirectoryEntry> Container = new List<DirectoryEntry>();
            do
            {
                if (string.IsNullOrEmpty(DcPath) || string.IsNullOrEmpty(DcRoot))
                {
                    bResult = false;
                    //rizhi
                    break;
                }
                string strRootDistinguishedName = DcPath.Substring(DcRoot.Length);
                //读取所有容器对象 不含dc
                if (!this.GetDCTree(DcPath,strRootDistinguishedName, out Container, out strError))
                {
                    bResult = false;
                    ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(string.Format(" GetDCTree error:{0}:", strError)));
                    break;
                }

                //将dc数据也添加到容器列表中
                DirectoryEntry DcEntry = new DirectoryEntry(DcPath, ADAccount, ADPassword);
                try
                {
                    DcEntry.RefreshCache();
                    DcEntry.Guid.ToString();
                }
                catch (Exception)
                {

                    DcEntry = null;
                }
                if (DcEntry == null)
                {
                    //bResult = false;
                    //rizhi
                    break;
                }

                Container.Add(DcEntry);

                //
                for (int i = 0; i < Container.Count; i++)
                {
                    if (string.IsNullOrEmpty(Convert.ToString(Container[i].Guid)))
                    {
                        continue;
                    }
                    try
                    {
                        OUEntity ou = new OUEntity();
                        ou.Guid = Container[i].Guid.ToString();
                        ou.DisplayName = Container[i].Properties["name"].Value == null ? "" : Container[i].Properties["name"].Value.ToString();
                        ou.ParentGuid = Container[i].SchemaClassName == "domainDNS" ? "0" : Convert.ToString(Container[i].Parent.Guid);
                        ou.DName = Container[i].Properties["distinguishedName"].Value == null ? "" : Container[i].Properties["distinguishedName"].Value.ToString();
                        ou.Parent_DName = Container[i].SchemaClassName == "domainDNS" ? "0" : Convert.ToString(Container[i].Parent.Name);
                        //ou.Sort = Container[i].Properties["telephoneNumber"].Value == null ? 999 : Convert.ToInt32(Container[i].Properties["telephoneNumber"].Value);
                        ou.Description = Container[i].Properties["description"].Value == null ? "" : Container[i].Properties["description"].Value.ToString();
                        //ou.Levele = 0;
                        ou.WhenChanged = DateTime.Parse(Convert.ToString(Container[i].Properties["whenChanged"].Value)).ToLocalTime();
                        ou.WhenCreated = DateTime.Parse(Convert.ToString(Container[i].Properties["whenCreated"].Value)).ToLocalTime();

                        OuList.Add(ou);

                    }
                    catch (Exception ex)
                    {
                        //ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(string.Format(" GetDCTree error:{0}:", strError))); 
                        ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(string.Format(" 读取组织：{0}信息异常, error:{1}", Convert.ToString(Container[i].Properties["name"].Value), ex.ToString())));
                    }
                }

                //根据容器路径读取容器内非容器对象
                bool bGetContainerChildResult = true;
                for (int i = 0; i < Container.Count; i++)
                {
                    List<DirectoryEntry> TempContainerChild = null;
                    string TempContainerDistinguishedName = Convert.ToString(Container[i].Properties["distinguishedName"].Value);
                    if (!this.GetChildObjectByTreeNode(TempContainerDistinguishedName, 1000000, out TempContainerChild, out strError))
                    {
                        ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(string.Format(" 读取{0}子对象错误信息异常, error:{1}:", TempContainerDistinguishedName, strError)));
                        continue;
                    }

                    try
                    {

                        for (int j = 0; j < TempContainerChild.Count; j++)
                        {
                            UserEntity user = new UserEntity();
                            try
                            {

                                if (TempContainerChild[j].SchemaClassName.ToLower() == "user")
                                {
                                    int TempuserAccountControl = 0;
                                    if (TempContainerChild[j].Properties["userAccountControl"].Value != null)
                                        TempuserAccountControl = Convert.ToInt32(TempContainerChild[j].Properties["userAccountControl"][0]);
                                    user.Guid= Convert.ToString(TempContainerChild[j].Guid).Replace("'", "");
                                    user.SAMAccountName = TempContainerChild[j].Properties["sAMAccountName"] == null ? string.Empty : Convert.ToString(TempContainerChild[j].Properties["sAMAccountName"].Value).Replace("'", "");
                                    user.DName = TempContainerChild[j].Properties["distinguishedName"] == null ? string.Empty : Convert.ToString(TempContainerChild[j].Properties["distinguishedName"].Value).Replace("'", "");
                                    user.ParentGuid = Convert.ToString(TempContainerChild[j].Parent.Guid).Replace("'", "");
                                    user.Parent_DName = Convert.ToString(TempContainerChild[j].Parent.Properties["distinguishedName"].Value).Replace("'", "");
                                    user.UserPrincipalName = Convert.ToString(TempContainerChild[j].Properties["userPrincipalName"].Value);
                                    DateTime dtTempaccountExpires = Convert.ToDateTime("1900-01-01");
                                    user.AccountExpiresTime = dtTempaccountExpires > Convert.ToDateTime("1900-01-01") ? dtTempaccountExpires : Convert.ToDateTime("1900-01-01");
                                    long TemppwdLastSet = 0;
                                    if (TempContainerChild[j].Properties["pwdLastSet"].Value != null)
                                        TemppwdLastSet = GetLongValue((IADsLargeInteger)TempContainerChild[j].Properties["pwdLastSet"].Value);
                                    user.ChangePwdNext = TemppwdLastSet > 0 ? false : true;
                                    user.PasswordNerverExpire = (TempuserAccountControl & 65536) != 0 ? true : false;
                                    ActiveDs.IADsUser native = (ActiveDs.IADsUser)TempContainerChild[j].NativeObject;
                                    user.PasswordExpireTime = native.PasswordExpirationDate;
                                    user.PasswordExpired = (TempuserAccountControl & 8388608) != 0 ? true : false;
                                    user.WhenChanged = DateTime.Parse(Convert.ToString(TempContainerChild[j].Properties["whenChanged"].Value)).ToLocalTime();
                                    user.WhenCreated = DateTime.Parse(Convert.ToString(TempContainerChild[j].Properties["whenCreated"].Value)).ToLocalTime();
                                    user.IsDisable = (TempuserAccountControl & 2) != 0 ? true : false;
                                    user.IsLocked = Convert.ToBoolean(TempContainerChild[j].InvokeGet("IsAccountLocked"));
                                    user.Cn = Convert.ToString(TempContainerChild[j].Properties["cn"].Value).Replace("'", "");
                                    user.Sn = Convert.ToString(TempContainerChild[j].Properties["sn"].Value).Replace("'", "");
                                    user.GivenName = Convert.ToString(TempContainerChild[j].Properties["givenname"].Value).Replace("'", "");
                                    user.Displayname = Convert.ToString(TempContainerChild[j].Properties["displayname"].Value).Replace("'", "");
                                    user.Description = Convert.ToString(TempContainerChild[j].Properties["description"].Value).Replace("'", "");
                                    user.PhysicalDeliveryOfficeName = Convert.ToString(TempContainerChild[j].Properties["physicaldeliveryofficename"].Value).Replace("'", "");
                                    var proxyAddresses = TempContainerChild[j].Properties["proxyAddresses"].Value == null ? "" : TempContainerChild[j].Properties["proxyAddresses"].Value.ToString();
                                    if(proxyAddresses=="")
                                    {
                                        user.Mail = "";
                                    }
                                    else
                                    {
                                        string[] strproxyAddresses = proxyAddresses.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                                        for (int a = 0; a < strproxyAddresses.Length; a++)
                                        {
                                           if(strproxyAddresses[a].Contains("SMTP"))
                                            {
                                                user.Mail = strproxyAddresses[a].Replace("SMTP:",""); 
                                            }
                                        }
                                    }
                                    //user.Mail = Convert.ToString(TempContainerChild[j].Properties["mail"].Value).Replace("'", "");
                                    user.TelephoneNumber = Convert.ToString(TempContainerChild[j].Properties["telephonenumber"].Value).Replace("'", "");
                                    user.St = Convert.ToString(TempContainerChild[j].Properties["st"].Value).Replace("'", "");
                                    user.L = Convert.ToString(TempContainerChild[j].Properties["L"].Value).Replace("'", "");
                                    user.StreetAddress = Convert.ToString(TempContainerChild[j].Properties["streetaddress"].Value).Replace("'", "");
                                    user.PostalCode = Convert.ToString(TempContainerChild[j].Properties["postalcode"].Value).Replace("'", "");
                                    user.Mobile = Convert.ToString(TempContainerChild[j].Properties["mobile"].Value).Replace("'", "");
                                    user.Title = Convert.ToString(TempContainerChild[j].Properties["title"].Value).Replace("'", "");
                                    user.Department = Convert.ToString(TempContainerChild[j].Properties["department"].Value).Replace("'", "");
                                    user.Company = Convert.ToString(TempContainerChild[j].Properties["company"].Value).Replace("'", "");
                                    bool AccountNeverExpiredResult = false;
                                    long TempaccountExpires = 0;
                                    if (TempContainerChild[j].Properties["accountExpires"].Value != null)
                                        TempaccountExpires = GetLongValue((IADsLargeInteger)TempContainerChild[j].Properties["accountExpires"].Value);
                                    if (TempaccountExpires <= 0)
                                    {
                                        AccountNeverExpiredResult = true;
                                    }

                                    try
                                    {
                                        dtTempaccountExpires = DateTime.FromFileTime(TempaccountExpires);
                                    }
                                    catch (Exception)
                                    {
                                        AccountNeverExpiredResult = true;
                                    }
                                    user.AccountNeverExpired = AccountNeverExpiredResult;


                                    long Templastlogon = 0;
                                    if (TempContainerChild[j].Properties["lastlogon"].Value != null)
                                        Templastlogon = GetLongValue((IADsLargeInteger)TempContainerChild[j].Properties["lastlogon"].Value);
                                    user.LastLogin = Templastlogon > 0 ? DateTime.FromFileTimeUtc(Templastlogon) : Convert.ToDateTime("1900-01-01");
                                    //lync

                                    if (TempContainerChild[j].Properties.Contains("msRTCSIP-PrimaryUserAddress")
                                        && TempContainerChild[j].Properties["msRTCSIP-PrimaryUserAddress"].Value != null)
                                    {
                                        user.Lync_IsLyncUser = true;
                                        user.Lync_SipAddress = Convert.ToString(TempContainerChild[j].Properties["msRTCSIP-PrimaryUserAddress"].Value).Substring(4);
                                    }
                                    //exchange
                                    if (TempContainerChild[j].Properties.Contains("proxyAddresses")
                                    && TempContainerChild[j].Properties["proxyAddresses"].Value != null)
                                    {

                                        for (int m = 0; m < TempContainerChild[j].Properties["proxyAddresses"].Count; m++)
                                        {
                                            if (Convert.ToString(TempContainerChild[j].Properties["proxyAddresses"][m]).ToLower().Trim().Contains("smtp:"))
                                            {
                                                user.Exchange_IsExchangeUser = true;
                                                user.Exchange_PrimarySmtpName = Convert.ToString(TempContainerChild[j].Properties["proxyAddresses"][m]).ToLower().Trim();
                                            }
                                        }
                                    }


                                    user.UserType = UsetType.User;
                                    if (TempContainerChild[j].Properties["manager"].Value != null)
                                    {
                                        user.ManagedBy = Convert.ToString(TempContainerChild[j].Properties["manager"].Value);
                                    }
                                    //user.GroupType = user.GroupType;
                                    //user.ManagedBy = user.ManagedBy;
                                    //user.Sort = user.Sort;
                                    UserList.Add(user);
                                }
                                
                                



                               


                            }
                            catch (Exception ex)
                            {
                                Console.Write("异常");
                                ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(string.Format(" 读取人员：{0}信息异常, error:{1}", Convert.ToString(TempContainerChild[j].Properties["sAMAccountName"].Value), ex.ToString())));
                                continue;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        bGetContainerChildResult = false;
                        ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(string.Format(" 读取人员信息异常, error:{0}:", ex.ToString())));
                        break;
                    }
                }

                if (!bGetContainerChildResult)
                {
                    bResult = false;
                    ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(string.Format(" bGetContainerChildResult Is False")));
                    break;
                }
                //List转DT
                
                 oudt = ToDataTable<OUEntity>(OuList);
                 userdt = ToDataTable<UserEntity>(UserList);
                //存储容器对象/容器子对象数据
                
            } while (false);
            return Task.FromResult((bResult, oudt, userdt));
        }

        private bool GetDCTree(string DcPath,string strdistinguishedName, out List<DirectoryEntry> NodeList, out string strError)
        {

            bool bResult = true;
            strError = string.Empty;
            NodeList = new List<DirectoryEntry>();

            try
            {
                do
                {
                    List<DirectoryEntry> FirstNodeList = new List<DirectoryEntry>();
                    if (!GetFisrtLevelNode(strdistinguishedName, out FirstNodeList, out strError))
                    {
                        strError = string.Format("GetDCTree GetFisrtLevelNode Error:{0}", strError);
                        bResult = false;
                        break;
                    }

                    if (FirstNodeList.Count > 0)
                    {
                        bool bResult_GetAllChildNode = true;
                        for (int i = 0; i < FirstNodeList.Count; i++)
                        {
                            List<DirectoryEntry> TempList = new List<DirectoryEntry>();
                            if (!GetAllChildTreeNodeByFirstLevelNode(DcPath,FirstNodeList[i], out TempList, out strError))
                            {
                                strError = string.Format("GetDCTree GetAllChildTreeNodeByFirstLevelNode ParentNodeName:{1} Error:{0}", strError, FirstNodeList[i].Name);
                                bResult_GetAllChildNode = false;
                                break;
                            }

                            for (int m = 0; m < TempList.Count; m++)
                            {
                                if (!NodeList.Contains(TempList[m]))
                                {
                                    NodeList.Add(TempList[m]);
                                }
                            }
                        }

                        if (!bResult_GetAllChildNode)
                        {
                            bResult = false;
                            break;
                        }
                    }
                } while (false);

            }
            catch (Exception ex)
            {
                strError = string.Format("GetDCTree Exception:{0}", ex.ToString());
                bResult = false;
            }

            return bResult;
        }

        private bool GetAllChildTreeNodeByFirstLevelNode(string DcPath,DirectoryEntry ParentNode, out List<DirectoryEntry> NodeList, out string strError)
        {
            bool bResult = true;
            NodeList = new List<DirectoryEntry>();
            strError = string.Empty;

            try
            {
                do
                {
                    if (string.IsNullOrEmpty(DcPath))
                    {
                        strError = "DC为空";
                        bResult = false;
                        break;
                    }

                    DirectorySearcher Ad_deSearch = new DirectorySearcher();
                    Ad_deSearch.SearchRoot = ParentNode;

                    List<string> TreeObjectClassList = new List<string>();
                    TreeObjectClassList = strTreeObjectClassNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList<string>();
                    if (TreeObjectClassList.Count > 0)
                    {
                        string strTemp = string.Empty;

                        for (int i = 0; i < TreeObjectClassList.Count; i++)
                        {
                            strTemp += "(objectClass=" + TreeObjectClassList[i] + ")";
                        }

                        Ad_deSearch.Filter = "(|" + strTemp + ")";
                    }

                    Ad_deSearch.SearchScope = SearchScope.Subtree;
                    Ad_deSearch.PageSize = 100000;
                    SearchResultCollection results = Ad_deSearch.FindAll();

                    if (results != null && results.Count > 0)
                    {
                        foreach (SearchResult Result in results)
                        {

                            DirectoryEntry Temp = Result.GetDirectoryEntry();

                            NodeList.Add(Temp);
                        }

                    }


                } while (false);
            }
            catch (Exception ex)
            {

                strError = string.Format("GetAllChildTreeNodeByFirstLevelNode Exception:{0}", ex.ToString());
                bResult = false;
            }

            return bResult;
        }

        private bool GetFisrtLevelNode(string strdistinguishedName, out List<DirectoryEntry> NodeList, out string strError)
        {
            bool bResult = true;
            NodeList = new List<DirectoryEntry>();
            strError = string.Empty;
            try
            {
                do
                {
                    if (string.IsNullOrEmpty(strdistinguishedName))
                    {
                        strError = "路径为空";
                        bResult = false;
                        break;
                    }


                    DirectoryEntry RootEntry = new DirectoryEntry(DcRoot + strdistinguishedName, ADAccount, ADPassword);
                    DirectorySearcher Ad_deSearch = new DirectorySearcher();
                    Ad_deSearch.SearchRoot = RootEntry;

                    List<string> TreeObjectClassList = new List<string>();
                    TreeObjectClassList = strTreeObjectClassNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList<string>();
                    if (TreeObjectClassList.Count > 0)
                    {
                        string strTemp = string.Empty;

                        for (int i = 0; i < TreeObjectClassList.Count; i++)
                        {
                            strTemp += "(objectClass=" + TreeObjectClassList[i] + ")";
                        }

                        Ad_deSearch.Filter = "(|" + strTemp + ")";
                    }

                    Ad_deSearch.SearchScope = SearchScope.OneLevel;
                    Ad_deSearch.PageSize = 100000;
                    SearchResultCollection results = Ad_deSearch.FindAll();

                    if (results != null && results.Count > 0)
                    {

                        List<string> TreeObjectNameList = new List<string>();

                        foreach (SearchResult Result in results)
                        {
                            DirectoryEntry Temp = Result.GetDirectoryEntry();
                            NodeList.Add(Temp);
                        }
                    }

                } while (false);
            }
            catch (Exception ex)
            {
                strError = string.Format("GetFisrtLevelNode Exception:{0}", ex.ToString());
                bResult = false;
            }

            return bResult;
        }

        private bool GetChildObjectByTreeNode(string strdistinguishedName, int pageSize, out List<DirectoryEntry> NodeList, out string strError)
        {
            bool bResult = true;
            strError = string.Empty;
            NodeList = new List<DirectoryEntry>();

            try
            {
                do
                {
                    DirectoryEntry RootEntry = new DirectoryEntry(DcRoot + strdistinguishedName.Replace("/", "\\/"), ADAccount, ADPassword);
                    RootEntry.RefreshCache();

                    DirectorySearcher Ad_deSearch = new DirectorySearcher();
                    Ad_deSearch.SearchRoot = RootEntry;
                    List<string> ObjectClassNameList = new List<string>();
                    ObjectClassNameList = strObjectClassNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList<string>();
                    if (ObjectClassNameList.Count > 0)
                    {
                        string strTemp = string.Empty;

                        for (int i = 0; i < ObjectClassNameList.Count; i++)
                        {
                            strTemp += "(objectClass=" + ObjectClassNameList[i] + ")";
                        }

                        Ad_deSearch.Filter = "(|" + strTemp + ")";
                    }
                    Ad_deSearch.SearchScope = SearchScope.OneLevel;
                    Ad_deSearch.PageSize = 100000;
                    Ad_deSearch.SizeLimit = pageSize;
                    SearchResultCollection results = Ad_deSearch.FindAll();

                    if (results != null && results.Count > 0)
                    {
                        foreach (SearchResult Result in results)
                        {
                            DirectoryEntry Temp = Result.GetDirectoryEntry();
                            NodeList.Add(Temp);
                        }
                    }
                } while (false);

            }
            catch (Exception ex)
            {
                strError = string.Format("GetChildObjectByTreeNode Exception:{0}", ex.ToString());
                bResult = false;
            }

            return bResult;
        }

        /// <summary>
        /// list转dataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        private static DataTable ToDataTable<T>(IList<T> data)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable dt = new DataTable();
            for (int i = 0; i < properties.Count; i++)
            {
                PropertyDescriptor property = properties[i];
                dt.Columns.Add(property.Name, property.PropertyType);
            }
            object[] values = new object[properties.Count];
            foreach (T item in data)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = properties[i].GetValue(item);
                }
                dt.Rows.Add(values);
            }
            return dt;
        }

        public static bool InsertToDataBase(String strSqlConn, DataTable OUdt, DataTable Userdt)
        {
            string strTableNameOU = "AD_OU_Temp";//temp表OU
            string strTableNameUser = "AD_User_Temp";//temp表User
            bool bResult = true;
            string strError = string.Empty;
            do
            {
                

                bool InsertOuResult = true;
                if (OUdt != null && OUdt.Rows.Count > 0)
                {
                    ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity("============================获取OU数据成功! count:" + OUdt.Rows.Count.ToString() + "============================"));

                    if (!SqlBulkCopyInsert(strSqlConn, strTableNameOU, OUdt))
                    {
                        ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(" *********************插入OU信息失败, error:" + strError + " ***sql:" + "DataTableCopy"));
                        InsertOuResult = false;
                        break;
                    }
                }
                ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(" *********************插入OU信息成功, error:" + strError));
                if (!InsertOuResult)
                {
                    bResult = false;
                    break;
                }



                

                
                

                bool InsertUserResult = true;
                if (Userdt != null && Userdt.Rows.Count > 0)
                {
                    ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity("============================获取User数据成功! count:" + Userdt.Rows.Count.ToString() + "============================"));

                    if (!SqlBulkCopyInsert(strSqlConn, strTableNameUser, Userdt))
                    {
                        ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(" *********************插入User信息失败, error:" + strError + "  **sql:" + "DataTableCopy"));
                        InsertUserResult = false;

                        break;
                    }


                }

                if (!InsertUserResult)
                {
                    bResult = false;
                    break;
                }
                ULogWork.CLogToTxtFile.RecordOperateLog(new EOperateLogEntity(" *********************插入User信息成功, error:" + strError));



                
                

                
            } while (false);

            return bResult;
        }

        #region 使用SqlBulkCopy将DataTable中的数据批量插入数据库中
        /// <summary>  
        /// 注意：DataTable中的列需要与数据库表中的列完全一致。 
        /// </summary>  
        #endregion
        private static bool SqlBulkCopyInsert(string strSqlConn, string strTableName, DataTable dt)
        {
            SqlTransaction tran = null;
            bool bResult = true;
            try
            {
                using (SqlConnection conn = new SqlConnection(strSqlConn))
                {
                    conn.Open();
                    using (tran = conn.BeginTransaction())
                    {
                        using (SqlBulkCopy sqlRevdBulkCopy = new SqlBulkCopy(strSqlConn))
                        {
                            sqlRevdBulkCopy.DestinationTableName = strTableName;
                            sqlRevdBulkCopy.NotifyAfter = dt.Rows.Count;
                            sqlRevdBulkCopy.WriteToServer(dt);
                            tran.Commit();
                            sqlRevdBulkCopy.Close();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (null != tran)
                    tran.Rollback();
                bResult = false;
                throw (ex);
            }
            return bResult;
        }

        [ComImport]
        [Guid("9068270B-0939-11D1-8BE1-00C04FD8D503")]
        [InterfaceType(ComInterfaceType.InterfaceIsDual)]
        internal interface IADsLargeInteger
        {
            [DispId(0x00000002)]
            int HighPart { get; set; }
            [DispId(0x00000003)]
            int LowPart { get; set; }
        }

        internal static long GetLongValue(IADsLargeInteger value)
        {
            return (long)(((ulong)value.HighPart << 32) + (ulong)value.LowPart);
        }
    }
}
